package cn.com.frame.core.job;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
@Scope("singleton")
public class QuartzManager {
    private static final Logger logger = LoggerFactory.getLogger(QuartzManager.class);
    private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();
    private static final String JOB_DEFAULT_GROUP_NAME = "job_def_group_name";
    private static final String TRIGGER_DEFAULT_GROUP_NAME = "trigger_def_group_name";
    private Scheduler scheduler;

    /**
     * 添加定时JOB
     * @param jobName   任务名称（唯一）
     * @param jobClass  执行任务类
     * @param cronExp   执行规则  （  "0 0/1 * * * ?"  =  每一分钟执行一次）
     * @param startTime 多久后开始执行  单位毫秒  （1000*60  =  1 分钟 ）
     * @param newJobDataMap 数据 ,在执行任务的时候可以取出来
     * @return
     */
    public boolean addJob(String jobName, Class jobClass, String cronExp,long startTime,JobDataMap newJobDataMap){

        if (!CronExpression.isValidExpression(cronExp)) {
            logger.error("Illegal cron expression format({})", cronExp);
            return false;
        }

        try {
            ////创建调度器Schedule
            if(scheduler == null){

                this.scheduler = schedulerFactory.getScheduler();
            }

            //创建JobDetail实例，并与HelloWordlJob类绑定
            /*JobDetail jobDetail = JobBuilder.newJob().withIdentity(new JobKey(jobName, JOB_DEFAULT_GROUP_NAME))
                    .ofType(jobClass)
                    .build();*/
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(new JobKey(jobName, JOB_DEFAULT_GROUP_NAME))
                    .setJobData(newJobDataMap)
                    .build();

            Date startDate = new Date(); //多久后开始执行
            if(startTime >0){
                startDate.setTime(startDate.getTime()+startTime);
            }
            //创建触发器Trigger实例
            Trigger trigger = TriggerBuilder.newTrigger()
                    .forJob(jobDetail)
                    .withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
                    .withIdentity(jobName,TRIGGER_DEFAULT_GROUP_NAME)
                    .startAt(startDate)
                    .build();
            //开始执行
            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();

        } catch (Exception e) {
            logger.error("QuartzManager add job failed", e);
            return false;
        }
        return true;

    }

    /**
     *  删除定时JOB
     * @param jobName
     * @return
     */
    public boolean deleteJob(String jobName){
        JobKey jobKey = new JobKey(jobName, JOB_DEFAULT_GROUP_NAME);

        try {
            if (scheduler.checkExists(jobKey)) {
                return scheduler.deleteJob(jobKey);
            } else {
                logger.error("delete job name:{},group name:{} not exists.", jobKey.getName(), jobKey.getGroup());
            }
        } catch (SchedulerException e) {
            logger.error(e.getMessage(), e);
            logger.error("delete job name:{},group name:{} failed!", jobKey.getName(), jobKey.getGroup());
            return false;
        }
        return true;
    }

    /**
     * 更新定时Job 规则
     * @param jobName
     * @param cronExp
     * @return
     */
    public boolean updateJob(String jobName, String cronExp) {

        if (!CronExpression.isValidExpression(cronExp)) {
            logger.error("Illegal cron expression format({})", cronExp);
            return false;
        }
        JobKey jobKey = new JobKey(jobName, JOB_DEFAULT_GROUP_NAME);
        TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_DEFAULT_GROUP_NAME);
        try {
            if (scheduler.checkExists(jobKey) && scheduler.checkExists(triggerKey)) {
                JobDetail jobDetail = scheduler.getJobDetail(jobKey);
                Trigger newTrigger = TriggerBuilder.newTrigger()
                        .forJob(jobDetail)
                        .withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
                        .withIdentity(new TriggerKey(jobName, TRIGGER_DEFAULT_GROUP_NAME))
                        .build();
                scheduler.rescheduleJob(triggerKey, newTrigger);
            } else {
                logger.error("update job name:{},group name:{} or trigger name:{},group name:{} not exists..",
                        jobKey.getName(), jobKey.getGroup(), triggerKey.getName(), triggerKey.getGroup());
                return false;
            }
        } catch (SchedulerException e) {
            logger.error(e.getMessage(), e);
            logger.error("update job name:{},group name:{} failed!", jobKey.getName(), jobKey.getGroup());
            return false;
        }
        return true;
    }

}

